﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WithDelegats
{
    delegate void TypeOfSorting<T>(ref T itemA, ref T itemB);

    public class Sortings<T> where T : IComparable
    {
        /// <summary>
        /// Initialize object of Sortings class
        /// </summary>
        /// <param name="typeSorting"></param>
        public Sortings(string typeSorting)
        {
            this.mTypeSorting = typeSorting;
        }

        /// <summary>
        /// Method Swaping for ascending sorting
        /// </summary>
        /// <param name="itemA"></param>
        /// <param name="itemB"></param>
        private static void SwapForAscendingSorting(ref T itemA, ref T itemB)
        {
            if (itemA.CompareTo(itemB) > 0)
            {
                T temp = itemA;
                itemA = itemB;
                itemB = temp;
            }
        }

        /// <summary>
        /// Method Swaping for descending sorting
        /// </summary>
        /// <param name="itemA"></param>
        /// <param name="itemB"></param>
        private static void SwapForDescendingSorting(ref T itemA, ref T itemB)
        {
            if (itemA.CompareTo(itemB) < 0)
            {
                T temp = itemA;
                itemA = itemB;
                itemB = temp;
            }
        }

        /// <summary>
        /// Bubble sorting method
        /// </summary>
        /// <param name="mass"></param>
        public void Sort(ref T[] mass)
        {
            for (int i = 0; i < mass.Length - 1; i++)
            {
                for (int j = i + 1; j < mass.Length; j++)
                {
                    Swap(ref mass[i], ref mass[j]);
                }
            }
        }

        /// <summary>
        /// Method Swap
        /// </summary>
        /// <param name="itemA"></param>
        /// <param name="itemB"></param>
        private void Swap(ref T itemA, ref T itemB)
        {
            TypeOfSorting<T> deleg;

            switch (mTypeSorting)
            {
                case "des":
                case "Des":
                    deleg = SwapForDescendingSorting;
                    break;
                case "asc":
                case "Asc":
                    deleg = SwapForAscendingSorting;
                    break;
                default: 
                    throw new NotSupportedException(mTypeSorting);
            }

            deleg(ref itemA, ref itemB);
        }

        private string mTypeSorting;
    }
}
